package org.yelongframework.qrcode.impl.zxing;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.StringUtils;
import org.yelongframework.qrcode.QRCodeErrorCorrectionLevel;
import org.yelongframework.qrcode.QRCodeProperties;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * google zxing 实现的二维码工具
 * 
 * @since 1.0.0
 */
public class DefaultZxingQRCodeTools implements ZxingQRCodeTools {

	@Override
	public OutputStream encode(String content, QRCodeProperties qrCodeProperties, OutputStream outputStream)
			throws IOException {
		String imageType = qrCodeProperties.getImageType();
		if (StringUtils.isBlank(imageType)) {
			throw new IllegalArgumentException("imageType cannot be null");
		}
		ZxingEncodeQRCodeConfig encodeQRCodeConfig = new ZxingEncodeQRCodeConfig();
		int width = qrCodeProperties.getWidth();
		int height = qrCodeProperties.getHeight();
		// 外边距
		Integer margin = qrCodeProperties.getMargin();
		if (null == margin) {

		} else if (0 == margin) {
			encodeQRCodeConfig.setRemoveWhiteBorder(true);
		} else {
			encodeQRCodeConfig.setMargin(margin);
		}
		// 纠错能力
		QRCodeErrorCorrectionLevel qrCodeErrorCorrectionLevel = qrCodeProperties.getQrCodeErrorCorrectionLevel();
		if (null != qrCodeErrorCorrectionLevel) {
			encodeQRCodeConfig.putHint(EncodeHintType.ERROR_CORRECTION,
					ErrorCorrectionLevel.valueOf(qrCodeErrorCorrectionLevel.name()));// 纠错能力
		}
		encodeQRCodeConfig.putHint(EncodeHintType.CHARACTER_SET, qrCodeProperties.getCharset());// 编码
		BufferedImage bufferedImage = null;
		try {
			bufferedImage = ZxingQRCodeUtils.encodeReturnBufferedImage(content, width, height, encodeQRCodeConfig);
		} catch (WriterException e) {
			throw new IOException(e);
		}
		ImageIO.write(bufferedImage, imageType, outputStream);
		return outputStream;
	}

	@Override
	public String decodeReturnString(InputStream inputStream) throws IOException {
		BufferedImage bufferedImage = ImageIO.read(inputStream);
		Reader reader = new QRCodeReader();
		LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
		HybridBinarizer binarizer = new HybridBinarizer(source);
		BinaryBitmap image = new BinaryBitmap(binarizer);
		try {
			Result result = reader.decode(image);
			return result.getText();
		} catch (Exception e) {
			throw new IOException(e);
		}
	}

}
